<?php

namespace addons\csmitsm\library\xcore\xcore\base;

use think\Db;
use Exception;
use fast\Tree;
use think\Loader;
use think\addons\Service;
use app\admin\model\Admin;
use think\exception\PDOException;
use app\common\controller\Backend;
use think\exception\ValidateException;
use addons\csmitsm\library\xcore\xcore\XcException;
use addons\csmitsm\library\xcore\xcore\utils\XcDaoUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcConfigUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcRequestUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcTransactionUtils;
use addons\csmitsm\library\xcore\xcore\utils\XcAdminSessionUtils;

/**
 * Backend的基础类(admin control的基类)
 */
abstract class XcABackend extends Backend
{

    /**
     * getControlPath() -> csmitsm/xcmyflowinstance
     * @return string
     */
    protected function getControlPath()
    {
        $controllername = Loader::parseName($this->request->controller());
        return str_replace('.', '/', $controllername) . '/';
    }

    protected function fetchIframePage($src, $xdebugSrc = '')
    {
        $xdebug = XcRequestUtils::get("xdebug", false, (XcConfigUtils::isXcDebug() === true) ? "Y" : "N");

        $token = null;
        if (true) {
            $admin = Admin::get(XcAdminSessionUtils::getUserId());
            $token = $admin->token;
        }

        $src = XcRequestUtils::appendUrlParams($src, ["clogintoken" => $token]);
        $xdebugSrc = XcRequestUtils::appendUrlParams($xdebugSrc, ["clogintoken" => $token]);

        $this->assign("src", ($xdebug == 'Y') ? $xdebugSrc : $src);
        $this->assign("xdebug", $xdebug);
        return $this->fetch(XcConfigUtils::getAddonCode() . "/xcore/page_iframe");
    }

    protected function beforeAddPage()
    {
        trace("beforeAddPage");
    }

    protected function afterAddSubmit($row)
    {
        trace("afterAddSubmit");
    }
    protected function beforeAddSubmit(&$params)
    {
        trace("beforeAddSubmit");
    }

    public function add()
    {
        if (false === $this->request->isPost()) {
            $this->beforeAddPage();
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);

        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
            $params[$this->dataLimitField] = $this->auth->id;
        }
        $result = false;

        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                $this->model->validateFailException()->validate($validate);
            }

            $this->beforeAddSubmit($params);

            $result = $this->model->allowField(true)->save($params);

            $this->afterAddSubmit($this->model);

            Db::commit();
        } catch (ValidateException | PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result === false) {
            $this->error(__('No rows were inserted'));
        }
        $this->success();
    }

    protected function beforeEditPage(&$params)
    {
        trace("beforeEditPage");
    }
    protected function afterEditSubmit($row)
    {
        trace("afterEditSubmit");
    }
    protected function beforeEditSubmit(&$params)
    {
        trace("beforeEditSubmit");
    }
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->beforeEditPage($row);
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            //是否采用模型验证
            if ($this->modelValidate) {
                $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                $row->validateFailException()->validate($validate);
            }

            $this->beforeEditSubmit($params);

            $result = $row->allowField(true)->save($params);

            $this->afterEditSubmit($row);

            Db::commit();
        } catch (ValidateException | PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    protected function afterDelSubmit($row)
    {
        trace("afterDelSubmit");
    }
    protected function beforeDelSubmit(&$params)
    {
        trace("beforeDelSubmit");
    }
    public function del($ids = null)
    {
        if (false === $this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ?: $this->request->post("ids");
        if (empty($ids)) {
            $this->error(__('Parameter %s can not be empty', 'ids'));
        }
        $pk = $this->model->getPk();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        $list = $this->model->where($pk, 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                $this->beforeDelSubmit($item);
                $count += $item->save([
                    'status' => 'hidden'
                ]);
                $this->afterDelSubmit($item);
            }
            Db::commit();
        } catch (PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error(__('No rows were deleted'));
    }


    /**
     * 发布菜单界面, 参照csmitsm的csmitsm/xcflowmdm/index管理
     * 
     * 1. 对应表增加字段
        `menuname` varchar(255) DEFAULT NULL COMMENT '菜单名称',
        `menu_id` int(11) DEFAULT NULL COMMENT '菜单',
     * 2. Control增加 
        public function publishmenu()
        {
            return $this->_publishmenu("csmitsm/xcflowchartpage/index?xcflowchartpage_id=[[id]]");
        }
     * 3. 增加lang
        'Menuname'   => '菜单名称',
        'Menu_id'    => '菜单',
     * 4. xpconfig配置
         ["code" => "Xcflowviewpage#publishmenu", "name" => "菜单发布", "url" => "csmitsm/xcflowviewpage/publishmenu?id=[[id]]&dialog=1"],
     * 5. js增加方法 
        publishmenu: function () {
            Controller.api.bindevent();
        },
     */
    protected $publishmenu_path = null;
    protected function _publishmenu($publishmenu_path)
    {
        $id = XcRequestUtils::get("id", true);
        $row = XcDaoUtils::getRowById($this->model, $id);

        if (empty($publishmenu_path)) {
            throw new XcException("参数配置错误", 0, null, "Control类缺少参数publishmenu_path定义");
        }

        if (false === $this->request->isPost()) {
            // copy from Rule.php
            if (true) {
                $rulelist = [];
                // 必须将结果集转换为数组
                $ruleList2 = \think\Db::name("auth_rule")->field('type,condition,remark,createtime,updatetime', true)->order('weigh DESC,id ASC')->select();
                foreach ($ruleList2 as $k => &$v) {
                    $v['title'] = __($v['title']);
                }
                unset($v);
                Tree::instance()->init($ruleList2)->icon = ['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;&nbsp;&nbsp;&nbsp;'];
                $rulelist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0), 'title');
                $ruledata = [0 => __('None')];
                foreach ($rulelist as $k => &$v) {
                    if (!$v['ismenu']) {
                        continue;
                    }
                    $ruledata[$v['id']] = $v['title'];
                    unset($v['spacer']);
                }
                unset($v);
                $this->view->assign('ruledata', $ruledata);
            }
            // get menu_parent_id
            if (!empty($row->menu_id)) {
                $authRule = XcDaoUtils::getRowById(new \app\admin\model\AuthRule(), $row->menu_id);
                $this->view->assign('pid', $authRule->pid);
            } else {
                $this->view->assign('pid', -1);
            }
            $this->view->assign('row', $row);
            $this->view->assign('menuname', empty($row->menuname) ? $row->name : $row->menuname);
            return $this->fetch(XcConfigUtils::getAddonCode() . "/xcore/page_publishmenu");
        } else {
            $pid = XcRequestUtils::post("pid", true, null, "父窗口 必填");
            $menuname = XcRequestUtils::post("menuname", true);


            XcTransactionUtils::service(function () use ($row, $pid, $menuname, $publishmenu_path) {
                $publishmenu_path = str_replace("[[id]]", $row->id, $publishmenu_path);

                if (empty($row->menu_id)) {
                    $authrule = XcDaoUtils::create(new \app\admin\model\AuthRule(), [
                        'type' => 'menu',
                        'pid' => $pid,
                        'name' => $publishmenu_path,
                        'title' => $menuname,
                        'icon' => 'fa fa-circle-o',
                        'ismenu' => 1,
                        'status' => 'normal'
                    ]);
                    $row->save([
                        'menu_id' => $authrule->id,
                        'menuname' => $menuname,
                    ]);
                } else {
                    $authRule = XcDaoUtils::getRowById(new \app\admin\model\AuthRule(), $row->menu_id);
                    $authRule->save([
                        'pid' => $pid,
                        'name' => $publishmenu_path,
                    ]);
                    $row->save([
                        'menuname' => $menuname,
                    ]);
                }
                // clear cache
                rmdirs(CACHE_PATH, false);
                rmdirs(TEMP_PATH, false);
                Service::refresh();
            });

            $this->success();
        }
    }

    /*
    此部分为port的代码使用说明：

    如果要对象有port页面，则copy如下代码：
{$xp_currentnav_html}
<div class="panel panel-default panel-intro" style="background-color:#f1f4f6;">
    <div class="xc-block">
        <div class="xc-title">微信小程序码</div>
        <div class="xc-content">
            <image src="/api/csmitsm/xc_cweixin_mp_login/qcode_url?page={$page}&scene={$page}&width=600" width="300px" height="300px"></image>
        </div>
    </div>
    <div class="xc-block">
        <div class="xc-title">网页链接地址</div>
        <div class="xc-content"><a href='{$h5_url}' target="_blank">{$h5_url}</a></div>
        <image src="/api/csmitsm/xc_api/qcode_url?url={$h5_url}" width="300px" height="300px"></image>
    </div>
</div>
   
    public function port($ids){
        $id = $ids;

        $addons = XcConfigUtils::xpconfig("addons_code");
        $this->view->assign("h5_url",XcConfigUtils::config("xcbaseurl")."/assets/addons/{$addons}/h5/#/pages/{$addons}/conf?id={$id}");
        $this->view->assign("page",urlencode("/pages/csmitsm/conf"));
        $this->view->assign("scene",urlencode("id=6"));

        return $this->view->fetch();
    }
        
 */
}
